/*
 * Copyright (c) 2024 Huawei Technologies Co.,Ltd.
 *
 * openGauss is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *
 * http://license.coscl.org.cn/MulanPSL2
 *
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 * ---------------------------------------------------------------------------------------
 *
 * imcs_ctlg.h
 * routines to support common cache
 *
 * IDENTIFICATION
 * src/include/access/imcs/imcs_ctlg.h
 *
 * ---------------------------------------------------------------------------------------
 */

#ifndef IMCS_CTLG_H
#define IMCS_CTLG_H

#include "c.h"
#include "nodes/execnodes.h"
#include "utils/tuplesort.h"
#include <vector>
#include "catalog/gs_imcs.h"
#include "pgxc/pgxcnode.h"
#include <unordered_map>
#include "storage/htap/htap_delta_table.h"

#define Int2VectorSize(n) (offsetof(int2vector, values) + (n) * sizeof(int16))

typedef struct IMCSHashEntry {
    Oid rel_oid;
    Oid imcsoid;
    bool imcsispart;
    char *imcsstatus;
    bool imcsIsAvailable;
    List *colsIsAvailable;
    int2vector *imcskey;
    int imcsnattr;
    XLogRecPtr current_lsn;
    TupleTableSlot *slot;
} IMCSHashEntry;

typedef struct {
    Relation imcs_rel;
    TableScanDesc scan;
} IMCSScanContext;

typedef struct {
    htap::HTAPDelta *m_deltaExtractor;
    htap::HTAPDelta::StatsScanContext m_ctx;
} HTAPDeltaScanContext;

typedef struct {
    Oid imcs_oid;
    HASH_SEQ_STATUS *imcs_hash_seq;
    HASH_SEQ_STATUS *imcu_hash_seq;
} IMCSDescScanContext;

typedef struct {
    int cur_slot_id;
    int max_slot_id;
} IMCSCacheScanContext;

#define IMCS_MAX_ROWS_SIZE DefaultFullCUSize
#define IMCSTORED_NUM_BLOCKS_FOR_SCAN 1000

#define IMCS_STATUS_INITIAL "INITIAL"
#define IMCS_STATUS_ONSTANDBY "ONSTANDBY"
#define IMCS_STATUS_STARTING "STARTING"
#define IMCS_STATUS_COMPLETED "COMPLETED"
#define IMCS_STATUS_STORED "STORED"

#define TYPE_IMCSTORED 1
#define TYPE_UNIMCSTORED 2
#define TYPE_PARTITION_IMCSTORED 3
#define TYPE_PARTITION_UNIMCSTORED 4

extern void InitImcstore(Oid imcs_oid, Relation rel, bool isPartitioned);
extern void InitImcsOnStandby(Oid rel_id, StringInfo input_message);
extern void InitPartitionedImcstoreOnStandby(Oid rel_id, StringInfo input_message);
extern void InitImcuParallel(Relation rel, int2 *imcs_key, int imcs_natts);
extern void init_imcs_current_lsn(XLogRecPtr current_lsn);
extern void ClearBeforeReinitImcs(Relation rel);
extern void RemoveImcstore(Relation rel, std::unordered_map<Oid, RelFileNode> *oid_del_info, bool isPartitioned);
extern void RemoveImcstoreOnStandby(Oid rel_id);
extern void RemovePartitionedImcstoreOnStandby(Oid rel_id, StringInfo input_message);
extern void TruncateImcstore(Relation rel, std::unordered_map<Oid, RelFileNode> *oid_del_info);

extern int2vector *GetImcsKeys(Oid rel_oid);

extern void InitImcsHashTbl();

extern void UpdateImcHashTbl(Oid rel_oid, int natts, int2 *imcs_key, int imcs_natts, bool imcsstatus_judge = true);
extern void UpdateImcHashTblStatus(Oid rel_oid, char *imcs_status);
extern void AddSlotToImcHashTblInfoOnStandby(Oid rel_oid, TupleDesc tts_tupleDescriptor);
extern void AddToImcHashTbl(Oid rel_oid, Oid imcs_oid, bool is_partition, int2vector *imcskey, int nattrs,
    XLogRecPtr current_lsn);
extern void RemoveFromImcHashTbl(Oid rel_oid);
extern IMCSHashEntry *SearchImcHashTbl(Oid rel_oid);

extern void CreateImcDeltaTableForPartitions(Oid rel_id, Relation rel);
extern void CreateImcDeltaTable(Oid rel_id);
extern void CreatePartitionImcDeltaTable(Oid rel_id, Oid part_oid);
extern void DropImcDeltaTable(Oid rel_id, std::unordered_map<Oid, RelFileNode> **oid_del_info);
extern void DropImcDeltaTableForPartitions(Oid rel_id, Relation rel,
    std::unordered_map<Oid, RelFileNode> **oid_del_info);

extern PGXCNodeHandle **GetStandbyConnections(int *conn_count);
extern void SendUnImcstoredRequest(PGXCNodeHandle **connections, int conn_count, Oid rel_id);
extern void SendImcstoredRequest(PGXCNodeHandle **connections, int conn_count, Oid rel_id, List *columnlist,
    int length);
extern void SendPartitionedUnImcstoredRequest(PGXCNodeHandle **connections, int conn_count, Oid rel_id, Oid part_id,
    Oid subpart_id);
extern void SendPartitionedImcstoredRequest(PGXCNodeHandle **connections, int conn_count, Oid rel_id, Oid part_id,
    Oid subpart_id, List *columnlist, int length);

extern void CleanImcsHashTbl(Oid rel_oid);
extern Oid CreateImcsTableOnRel(CreateImcsStmt *imcs_stmt, bool is_partition, Oid parent_oid, Oid rel_oid,
    Relation rel);
extern void DeleteImcsTableOnRel(Oid rel_oid);
extern void ImcsNameFormRel(Oid rel_oid, bool is_partition, char *imcs_meta_name, char *imcs_meta_index_name);
extern bool CheckImcsSupportForRelType(Relation relation);
#endif